The present invention relates generally to software engineering, and specifically to methods of program control.
It is a common occurrence in computer system applications that a program thread must call a service provided by the system. For example, a program thread in a data migration and backup application typically needs to make multiple calls to read/write services on the source and target disks for the application. When the thread calls the service, it typically receives a response indicating whether or not the service is prepared to handle the call. Such a response might be xe2x80x9cproceedxe2x80x9d if the service completed sucessfully, xe2x80x9cwaitxe2x80x9d if the service is busy handling other requests, or xe2x80x9cerrorxe2x80x9d in the case of a fault.
The program thread must be prepared to handle these different sorts of responses in the appropriate way. Continuing with the preceding example, the program thread should respond to xe2x80x9cproceedxe2x80x9d by continuing the program flow corresponding to a successful completion of the service. When xe2x80x9cwaitxe2x80x9d is returned, the program thread should typically continue with other activities if possible, and then return to request the service again after a certain time has elapsed. Alternatively, the service notifies the program thread subsequently when it has completed the requested steps. In the case of xe2x80x9cerror,xe2x80x9d the thread should report the problem to the user or take other corrective action as appropriate.
The accepted way of handling these multiple cases is to define a separate callback function for handling each phase or state of the service, with each callback returning a code such as xe2x80x9cproceed,xe2x80x9d xe2x80x9cwaitxe2x80x9d or xe2x80x9cerror.xe2x80x9d This approach is conceptually straightforward, but in complex system applications, it leads to correspondingly complex program structures, with many different types of callbacks. This proliferation of non-uniform callback functions creates difficulties in writing and debugging the application software.
In preferred embodiments of the present invention, a single callback function is provided for use by a program thread in invoking a system service. The callback function contains multiple cases, each corresponding to a different state of the service. The service state is typically indicated by a return code that is returned by the service when it is invoked. The callback function uses a stack of case values to keep track of the state of the service. Whenever the function is called, it pops the most recent value from the stack in order to determine the current state of the service and, accordingly, to select the appropriate case to run using a case switch. In the course of running the selected case, the function typically pushes a new case value onto the stack, in order to indicate the next case to be selected.
The multi-case callback function structure of the present invention thus provides a uniform framework for all callbacks connected with a given service, eliminating the need to write a separate callback function for each possible state of the service or system. This framework can be used to create callback functions for substantially all of the system services that are to be invoked by an application, enabling the application to be structured and programmed in an orderly and transparent manner. Applications that are programmed in this manner are also easy to debug, by using a trace file of the interactions of the callback function with the pointer stack to follow the program flow in runtime.
There is therefore provided, in accordance with a preferred embodiment of the present invention, a method for invoking a service on a host processor in a computer-controlled system, including:
providing a single callback function having multiple cases, each such case corresponding to a state of the service;
creating a stack in a memory of the host processor, the stack containing one or more state descriptors indicative of the state of the service;
calling the function on the host processor in order to invoke the service;
responsive to calling the function, popping one of the state descriptors from the stack so as to determine the state of the service; and
running the case in the callback function that corresponds to the determined state.
Preferably, running the case includes pushing a further one of the descriptors onto the stack for use in determining the case in the single callback function that is to be run next. More preferably, calling the function includes requesting access to a resource of the system, and running the case includes running code so as to access the resource. Further preferably, running the case includes returning a code indicative of an outcome of the access. Most preferably, to branch from one case to another, a next one of the descriptors is popped from the stack and the case that corresponds to the next popped descriptor is run.
Preferably, calling the function includes calling a wrapper function when the service is invoked by a process thread, and the wrapper function pushes a first one of the descriptors onto the stack to be popped by the single callback function.
There is also provided, in accordance with a preferred embodiment of the present invention, computing apparatus, including:
a memory, arranged to store a stack containing one of more state descriptors indicative of a state of a service in a computer-controlled system; and
a host processor, which is arranged to invoke the service by calling a single callback function having multiple cases corresponding to the state of the service, such that responsive to calling the function, the processor pops one of the descriptors is popped from the stack so as to determine the state of the service, and runs the case in the callback function that corresponds to the determined state.
There is additionally provided, in accordance with a preferred embodiment of the present invention, a computer software product, comprising a computer-readable medium in which program instructions are stored, the instructions comprising a single callback function having multiple cases, each such case corresponding to a state of a service in a computer-controlled system, which instructions, when read by a computer, cause the computer to store a stack containing one of more state descriptors indicative of the state of the service, to invoke the service by calling the callback function, such that responsive to calling the function, one of the descriptors is popped from the stack so as to determine the state of the service, and to run the case in the callback function that corresponds to the determined state.
The present invention will be more fully understood from the following detailed description of the preferred embodiments thereof, taken together with the drawings in which: